<?php


namespace app\msgapi\service;

use app\utils\Arr;
use app\msgapi\model\{GroupChat, User, Cust};
use think\facade\Log;
error_reporting(E_ERROR | E_PARSE);
class HuihuaGroupChatService
{

    /**获取群组列表
     * @param $data
     * @return \think\response\Json
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public function getGroupChatLst($data,$admin_groupid,$adminid)
    {
        $limit = $data['limit']?:config('page.defaule_limit');
        $data['userid'] && $where[] = ['owner', '=', $data['userid']];
        $data['groupname'] && $where[] = ['name', 'like', "%{$data['groupname']}%"];
        $whereor = [];
        //有权限的所有成员
        $auth_user_arr = HsorganizationService::getDepartmentLst(2,0,$admin_groupid,$adminid);
        if(($auth_user_arr !== 'all') && empty($auth_user_arr)) return error_json('暂无成员权限');
        //成员权限
        if(($auth_user_arr !== 'all') && !empty($auth_user_arr) ){
            foreach ($auth_user_arr as $au_user)
            {
                $whereOr[] = "FIND_IN_SET('{$au_user}',`userid_list`)";
            }
        }
        if(isset($whereOr)) $whereor = implode(' OR ',$whereOr);//成员权限
        $list = GroupChat::with('userowner')->where($where)->where($whereor)->paginate($limit)->each(function ($item) {
            $userlist = User::field('name,userid,ispermit')->where('userid', 'in', $item['userid_list'])->select()->toArray();
            $custlistname = array_column($userlist,'name');
            $custlist = Cust::where('external_userid', 'in', $item['userid_list'])->select()->column('name');
            //判断群主是否是被监管人
            $ispermit = Arr::arrayGroupBy($userlist,'ispermit');
            if(isset($ispermit[1])){
                $ispermitlist = array_column($ispermit[1],'userid');
                if(in_array($item['owner'],$ispermitlist)){
                    $item['init_userid'] = $item['owner'];
                }else{
                    $item['init_userid'] = $ispermitlist[0];
                }
            }
            $groupmumber = array_merge($custlistname, $custlist);
            $item['groupmumber'] = $groupmumber;
            return $item;
        })->toArray();
        return success_json('成功',$list);
    }

    /**获取外部成员所在的群列表
     * @return array
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    public static function getGroupList()
    {
        $external_uid = input('external_uid/d');
        $externalinfo = Cust::findOrEmpty($external_uid)->toArray();
        $groupList = GroupChat::where("FIND_IN_SET('{$externalinfo['external_userid']}',`userid_list`)")
            ->with('userowner')->select()->each(function ($item) {
                $userlist = User::where('ispermit','>',0)->where('userid', 'in', $item['userid_list'])->column('userid');
                $custlistname = array_column($userlist,'name');
                $custlist = Cust::where('external_userid', 'in', $item['userid_list'])->select()->column('name');
                //判断群主是否是被监管人
                if(in_array($item['owner'],$userlist)){
                    $item['init_userid'] = $item['owner'];
                }else{
                    $item['init_userid'] =$userlist[0];
                }
                $groupmumber = array_merge($custlistname, $custlist);
                $item['groupmumber'] = $groupmumber;
                return $item;
            })->toArray();
        return $groupList;
    }


    /**同步群组
     * @return bool
     * @throws \think\Exception
     */
    public function synGroupInfo()
    {
        //同步群组数据，分两种，一种是外部群，一种是内部群，外部群分两种，一种是群主是监管人员的群组，一种是其他人的群组
        //获取被监管人列表
        $weworkCorpSelfService = new WeworkCorpSelfService();
        $monitorUserLst = $weworkCorpSelfService->getPermitUserList();
        if($monitorUserLst['errcode'] != 0){
            Log::write('获取被监管人列表失败,原因:'.$monitorUserLst['errmsg'],'error');
            return false;
        }
        $groupChatModel = new GroupChat();
        //获取已存储非监管人为群主的群组列表
        $otherLst = $groupChatModel->whereOr([
            ['owner','not in',$monitorUserLst['ids'],['type','=',2]],
            ['type','=',1]
        ])->column('chat_id');
        if(!empty($otherLst)){
            Log::write('已存储非监管人为群主的群组列表信息-更新开始.','info');
            foreach ($otherLst as $value){
                $this->queryGroupInfo($value,1);
            }
            Log::write('已存储非监管人为群主的群组列表信息-更新成功.','info');
        }
        $userModel = new User();
        //通过存档接口获取的被监管人可能会存在离职成员，需要先排除掉离职成员，再获取群组数据，否则会获取不到
        $userLst = $userModel->where('userid','in',$monitorUserLst['ids'])->column('userid');
        if( !$userLst || empty($userLst)){
            Log::write('获取被监管人列表失败,原因:被监管人员列表为空.','error');
            return false;
        }
        $cursor = '';
        do{
            $groupLst = $weworkCorpSelfService->getOutGroupList($userLst,$cursor,1);
//            echo json_encode($groupLst,256);
            if($groupLst['errcode'] == 0){
                foreach ($groupLst['group_chat_list'] as  $val){
                    $this->queryGroupInfo($val['chat_id'],1);
                }
                $cursor = $next = isset($groupLst['next_cursor'])?$groupLst['next_cursor']:'';
            }else{
                Log::write("获取外部群组列表失败,原因:errcode:{$groupLst['errcode']},errmsg:{$groupLst['errmsg']}",'warning');
//                return false;
            }
        }while($next != '');
        return true;
    }

    /**获取群组信息，有则返回，无则插入
     * @param string $roomid 群组id
     * @param int $updateflag 是否更新 0不更新 1更新
     * @return array|false
     * @throws \think\Exception
     */
    public function queryGroupInfo(string $roomid, int $updateflag = 0)
    {
        //群组信息也存在，直接返回相关信息
        $groupChatModel = new GroupChat();
        $groupInfoDb = $groupChatModel->where('chat_id', $roomid)->findOrEmpty()->toArray();
        if ($groupInfoDb && $updateflag == 0) return $groupInfoDb;
        $weworkCorpSelfService = new WeworkCorpSelfService();
        $groupInfo = $weworkCorpSelfService->getOutGroupInfo($roomid);
        if ($groupInfo['errcode'] == 0) {
            $roomdata = [
                'chat_id' => $roomid,
                'name' => $groupInfo['group_chat']['name']?:'群聊',
                'owner' => $groupInfo['group_chat']['owner'],
                'create_time' => $groupInfo['group_chat']['create_time'],
                'notice' => $groupInfo['group_chat']['notice'],
                'member_list' => $groupInfo['group_chat']['member_list'],
                'userid_list' => implode(',',array_column($groupInfo['group_chat']['member_list'], 'userid')),
                'type' => 2//外部群
            ];
        } else {
            if(in_array($groupInfo['errcode'], ['90501','49008'])) {
                if ($groupInfo['errcode'] == '90501') $info = '非客户群';
                if ($groupInfo['errcode'] == '49008') $info = '已解散群';
                Log::write("智能跳过--".$info,'info');
            } else {
                Log::write("外部群组信息获取失败(继续获取内部群组信息),原因:errcode:{$groupInfo['errcode']},errmsg:{$groupInfo['errmsg']}",'info');
            }

            $groupInfo = $weworkCorpSelfService->getInnerGroupInfo($roomid);
//            Log::write(json_encode($groupInfo,256));
            if ($groupInfo['errcode'] != 0) {
                if(in_array($groupInfo['errcode'], ['301059'])) {
                    if ($groupInfo['errcode'] == '301059') $info = '非内部群(外部群验证也失败)';
                    Log::write("智能跳过--".$info,'info');
                } else {
                    Log::write("内部群组信息获取失败,原因:errcode:{$groupInfo['errcode']},errmsg:{$groupInfo['errmsg']}", 'waring');
                }
            }
            $roomdata = [
                'chat_id' => $roomid,
                'name' => $groupInfo['roomname'],
                'owner' => $groupInfo['creator'],
                'create_time' => $groupInfo['room_create_time'],
                'notice' => $groupInfo['notice'],
                'member_list' => $groupInfo['members'],
                'userid_list' => implode(',',array_column($groupInfo['members'], 'memberid')),
                'type' => 1//内部群
            ];
        }
        if ($roomdata) {
            try {
                $groupInfoDb ? $groupChatModel->update($roomdata, ['id' => $groupInfoDb['id']]) : $groupChatModel->create($roomdata);
                return $roomdata;
            } catch (\Exception $e) {
                Log::write('群组信息存储失败,原因:' .$e->getMessage().'行号:'.$e->getLine(),'error');
            }
        }
        return false;
    }


    //**********************↓回调用↓************************

    /**客户群创建事件
     * @param $chat_id
     * @return bool
     * @throws \think\Exception
     */
    public static function getGroupDetail($chat_id)
    {
        $wework = new WeworkCorpSelfService();
        $group_info = $wework->getOutGroupInfo($chat_id);
        if($group_info['errcode'] !== 0){
            Log::write('[回调]群组信息获取失败,原因:'.$group_info['errmsg'].'错误码:'.$group_info['errcode'],'error');
            throw new \think\Exception('群组信息请求出错', $group_info['errcode']);
        }
        $group_info = $group_info['group_chat'];
//        Log::write(json_encode($group_info,256),'info');
        $groupchat = new GroupChat();
        $dbInfo = $groupchat->where('chat_id','=', $chat_id)->findOrEmpty()->toArray();
        $save_data = [
            'name' => $group_info['name'],
            'chat_id' => $group_info['chat_id'],
            'owner' => $group_info['owner'],
            'create_time' => $group_info['create_time'],
            'member_list' => $group_info['member_list'],
//            'admin_list' => $group_info['admin_list'],
            'userid_list' => array_column($group_info['member_list'], 'userid'),
            'notice' => $group_info['notice'],
            'type' => 2 //外部群固定为2,内部群固定为1
        ];
        try {
            if ($dbInfo) {
                $groupchat->update($save_data, ['id' => $dbInfo['id']]);
            } else {
                $groupchat->create($save_data);
            }
            Log::write("[回调]群组数据同步成功：{$save_data['name']}({$save_data['chat_id']})",'info');
            return true;
        } catch (\Exception $e) {
            Log::write("[回调]群组数据同步失败：{$save_data['name']},原因:" . $e->getMessage().'行号:'.$e->getLine() . 'data:'.json_encode($group_info,256),'error');
            return false;
        }
    }

    /**群组解散事件
     * @param $chatid
     * @return bool
     */
    public static function dismissGroup($chatid)
    {
        try {
            GroupChat::where('chat_id','=',$chatid)->update(['dismiss_flag' => 1]);
            Log::write("[回调]群组解散同步操作成功",'info');
            return true;
        } catch (\Exception $e) {
            Log::write("[回调]群组解散同步操作失败",'error');
        }
        return false;
    }
    //**********************↑回调用↑************************

}